﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

using Weazel.NativeMath;

using Microsoft.VisualStudio.TestTools.UnitTesting;

#endregion

namespace Weazel.NativeMath.Test
{
	[TestClass]
	public class TestShift
	{
		/**************************************************************************
		 * Left shift (<< operator)
		 **************************************************************************/
		//[TestMethod]
		//public void TestLeftShift_InvalidShiftValue_1()
		//{
		//  Integer i = new Integer(32, "0x00000001", false);

		//  try
		//  {
		//    Integer r = i << -12;
		//  }
		//  catch (ArgumentException)
		//  {
		//    return;
		//  }

		//  Assert.Fail();
		//}

		[TestMethod]
		public void TestLeftShift_Shift0Bits_1()
		{
			Integer i = new Integer(32, "0x00000001", false);

			Integer r = i << 0; // should not change anything

			Assert.AreEqual(i.ToDecimalString(), r.ToDecimalString());
		}

		[TestMethod]
		public void TestLeftShift_ShiftBeyondResultWidth_1()
		{
			Integer i = new Integer(32, "0x00000001", false);
			Integer r = new Integer(32, false);

			Integer.LeftShift(r, i, new Integer(16, 64, false).ToInt());

			Assert.IsTrue(r.IsZero());
		}

		[TestMethod]
		public void TestLeftShift_1()
		{
			Integer i = new Integer(32, "0x00000001", false);
			Integer r = i << 1;

			Assert.AreEqual("2", r.ToHexadecimalString());
			Assert.AreEqual(32, r.Width);
		}

		[TestMethod]
		public void TestLeftShift_2()
		{
			Integer i = new Integer(96, "0x000000010000000100000001", false);
			Integer r = i << 1;

			Assert.AreEqual("20000000200000002", r.ToHexadecimalString());
			Assert.AreEqual(96, r.Width);
		}

		[TestMethod]
		public void TestLeftShift_3()
		{
			Integer i = new Integer(96, "0x000000000000000100000000", false);
			Integer r = i << 8;

			Assert.AreEqual("10000000000", r.ToHexadecimalString());
			Assert.AreEqual(96, r.Width);
		}


		[TestMethod]
		public void TestLeftShift_4()
		{
			Integer i = new Integer(96, "0x000000000000000000000001", false);
			Integer r = i << 32;

			Assert.AreEqual("100000000", r.ToHexadecimalString());
			Assert.AreEqual(96, r.Width);
		}

		[TestMethod]
		public void TestLeftShift_5()
		{
			Integer i = new Integer(96, "0x107237252800120FA0329235", false);
			Integer v = new Integer(8, 36, false);
			Integer r = new Integer(96, false);
			Integer.LeftShift(r, i, v.ToInt());
			Assert.AreEqual("800120fa0329235000000000", r.ToHexadecimalString());
			Assert.AreEqual(96, r.Width);
		}

		[TestMethod]
		public void TestLeftShift_6()
		{
			Integer i = new Integer(96, "0x107237252800120FA0329235", false);
			Integer v = new Integer(8, 36, false);
			Integer r = new Integer(40, false);

			Integer.LeftShift(r, i, v.ToInt());

			Assert.AreEqual(40, r.Width);
			Assert.AreEqual("5000000000", r.ToHexadecimalString());
		}

		// right
		[TestMethod]
		public void TestRightShift_1()
		{
			Integer i = new Integer(32, "0x10000000", false);
			Assert.AreEqual("8000000", (i >> 1).ToHexadecimalString());
		}

		[TestMethod]
		public void TestRightShift_2()
		{
			Integer i = new Integer(96, "0x000000010000000100000001", false);
			Assert.AreEqual("8000000080000000", (i >> 1).ToHexadecimalString());
		}

		[TestMethod]
		public void TestRightShift_3()
		{
			Integer i = new Integer(96, "0x000000000000000100000000", false);
			Assert.AreEqual("1000000", (i >> 8).ToHexadecimalString());
		}


		[TestMethod]
		public void TestRightShift_4()
		{
			Integer i = new Integer(96, "0x000000000000000000000001", false);
			Assert.AreEqual("0", (i >> 32).ToHexadecimalString());
		}

		[TestMethod]
		public void TestRightShift_5()
		{
			Integer i = new Integer(96, "0x123456780000000012345678", false);
			Assert.AreEqual("1234567800000000", (i >> 32).ToHexadecimalString());
		}

		[TestMethod]
		public void TestRightShift_6()
		{
			Integer i = new Integer(96, "0x123456780000000012345678", false);
			Assert.AreEqual("123456780000000", (i >> 36).ToHexadecimalString());
		}

		// test arithmetic right shift

		[TestMethod]
		public void TestArithRightShift_1()
		{
			Integer i = new Integer(96, "8", true);
			Integer j = i << 92 >> 92;

			Assert.AreEqual("fffffffffffffffffffffff8", j.ToHexadecimalString());
		}

		[TestMethod]
		public void TestArithRightShift_2()
		{
			Integer i = new Integer(96, "8", true);
			Integer j = i << 88 >> 88;

			Assert.AreEqual("8", j.ToHexadecimalString());
		}
	}
}
